package com.ruoyi.web.controller.dc;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.CalendarUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ProcessStopException;
import com.ruoyi.common.utils.ExecUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.SseEmitterUtils;
import com.ruoyi.common.utils.biz.CommonUtil;
import com.ruoyi.common.utils.biz.PathUtil;
import com.ruoyi.common.utils.biz.ResultSaveModule;
import com.ruoyi.dm.domain.BO.SateInfoBO;
import com.ruoyi.dm.mapper.DataCollectionMapper;
import com.ruoyi.web.vo.CorrectCoefficientVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;


/**
 * <p>
 *  动态修正系统计算评估
 * </p>
 *
 * @author liuhl
 * @since 2024-04-15
 */
@RestController
@RequestMapping("/correctCoe")
@AllArgsConstructor
@Slf4j
@Api(tags = "动态修正系统计算评估")
public class CorrectCoefficientCalController {

    private DataCollectionMapper dataCollectionMapper;


    @GetMapping("/sates")
    @ApiOperation(value = "卫星列表获取", notes = "根据时间范围获取卫星列表", httpMethod = "GET")
    public AjaxResult getSatesList(CorrectCoefficientVo vo) {
        String startTime = vo.getStartTime();
        String endTime = vo.getEndTime();
        if (StrUtil.isBlank(startTime) || StrUtil.isBlank(endTime)){
            return AjaxResult.error("开始或结束时间为空");
        }


        //先去数据库中查一下有那些表 符合 SWDATA_OBS_DEN_*
        List<String> tableNames = dataCollectionMapper.selectAllTableNames("piesat_dgdq"); //大写最好
        if (CollUtil.isEmpty(tableNames)){
            return AjaxResult.error("模式: {} 下没有找到任何数据库表");
        }
        StringBuffer loginfo = new StringBuffer();
        List<String> sortedNames = tableNames
                .stream()
                .map(String::toUpperCase)
                .filter(name -> name.contains("SWDATA_OBS_DEN_"))
                .collect(Collectors.toList());

        List<SateInfoBO> finalTables = sortedNames.stream().map(tableName -> {
            SateInfoBO sateInfoBO = dataCollectionMapper.checkSatellite(tableName, startTime, endTime);
            sateInfoBO.setSatellite(tableName.replace("SWDATA_OBS_DEN_", ""));
            loginfo.append(String.format("检索 %s，数据详情:%s",tableName,sateInfoBO));
            loginfo.append("\n");
            return sateInfoBO;
        }).filter(bo -> bo.getNum()>1).collect(Collectors.toList());

        if (CollUtil.isEmpty(finalTables)){
            return AjaxResult.error("模式: {} 下没有找到任何符合搜索条件的数据");
        }

        //获取<卫星名，卫星高度范围> 的 map， 例如 <"CHAMP", "CHAMP--[397,417]">
        Map<String, String> sateNames = finalTables.stream()
                .collect(Collectors.toMap(SateInfoBO::getSatellite,
                value ->  {
                    return value.getSatellite()+"--["+Float.valueOf(value.getMinALt()/1000).intValue()+","+Float.valueOf(value.getMaxAlt()/1000).intValue()+"]";
                }));

        Map<String, Object> resultMap = MapUtil.builder(new HashMap<String, Object>())
                .put("log", loginfo.toString())
                .put("sates", sateNames)
                .build();

        return AjaxResult.success(resultMap);

    }


    @PostMapping("/cal")
    @ApiOperation(value = "计算", notes = "根据页面入参计算并推送日志", httpMethod = "POST")
    public AjaxResult windCharacterDraw(@RequestBody CorrectCoefficientVo vo) throws ProcessStopException {
        log.debug("动态修正系统计算评估-计算-入参: {}", vo);
        //每个卫星是一个线程，去执行 python3 cal_correction_factor.py /dgdq/config/modelCorrect/configuration.json
        //json中包含字段
        //    "calibration_start_time": "2003-10-16 00:00:00",  #这个就是页面的起始时间，格式保留不更改，前端可能传天 需要手动 + 00:00:00
        //    "calibration_end_time": "2004-01-01 00:00:00",
        //    "calibration_time_interval": "12", #不动
        //    "calibration_satellite_name":["GRACEA"], #如果选多个卫星，则生成多个config.json，每个卫星单独去调用python计算。
        //    "calibration_altitude_range":["397,417"],  #卫星列表获取返回的高度区间，由前端再次传回。
        //    "inital_obs_density_interval": "500",
        //    "dynamic_coefficient_numbers": "9", #要修改，修正系数的个数
        //    "computer_cores": "2", #不动
        //    "output__path": "/dgdq/output/modelCorrect/" #要修改成实际的

        // 计算python被调用后，会一直打印，直接先返回前端200成功。日志要SSE推送给前端，数据结构是：{"卫星1": "日志信息"}
        List<String> satellites = vo.getSatellites();
        if (CollUtil.isEmpty(satellites)){
            return AjaxResult.error("卫星列表为空");
        }
        String outputDir = PathUtil.outputDir() +
                PathUtil.moduleDirs().getModelCorrect().get("dir");

        String configDir = PathUtil.configDir() + PathUtil.moduleDirs().getModelCorrect().get("dir");

        String codePath = PathUtil.codeDir() +
                PathUtil.moduleDirs().getModelCorrect().get("dir") +
                PathUtil.moduleDirs().getModelCorrect().get("calculate");


        String startTime = vo.getStartTime() + " 00:00:00";
        String endTime = vo.getEndTime() + " 00:00:00";
        String coeNum = vo.getCoeNum();
        String sseId = vo.getSseId()+SecurityUtils.getLoginUser().getUsername();
        List<String> resList = Collections.synchronizedList(new ArrayList<String>());

        //isStop 表示进程是否终止
        AtomicBoolean isStop = new AtomicBoolean(false);
        List<CompletableFuture<Void>> futures = satellites.stream().map(satellite -> {
            AtomicReference<File> needDelete = new AtomicReference<>();
            return CompletableFuture.runAsync(() -> {
                try {
                    //1. 准备config.json文件中的内容
                    String[] split = satellite.split("--"); // "CHAMP--[397,417]"
                    String sateName = split[0];
                    String altitudeRange = split[1];

                    List<String> sateNameList = Stream.of(sateName).collect(Collectors.toList());
                    List<String> altitudeRangeList = Stream.of(
                                    altitudeRange.replace("[", "")
                                            .replace("]", ""))
                            .collect(Collectors.toList());

                    Map<String, Object> jsonMap = MapUtil.builder(new LinkedHashMap<String, Object>()) //需要顺序
                            .put("calibration_start_time", startTime)
                            .put("calibration_end_time", endTime)
                            .put("calibration_time_interval", vo.getFrequence())
                            .put("calibration_satellite_name", sateNameList)
                            .put("calibration_altitude_range", altitudeRangeList)
                            .put("inital_obs_density_interval", "500")
                            .put("dynamic_coefficient_numbers", coeNum)
                            .put("computer_cores", "2")
                            .put("output__path", outputDir)
                            .build();


                    //2. 生成这个json文件
                    String simpleUUID = IdUtil.simpleUUID();
                    String jsonPath = configDir + "/config____" + simpleUUID + ".json";
                    log.info("正在生成文件: {}", jsonPath);
                    File file = new File(jsonPath);
                    if (file.exists()) {
                        file.delete();
                    }
                    File writtenFile = FileWriter.create(file).write(JSONUtil.toJsonPrettyStr(jsonMap));
                    log.info("已生成文件: {}", jsonPath);
                    needDelete.set(writtenFile); //后面要删除的


                    //3. 执行python脚本
                    List<String> command = Stream.of("python",
                            "-u",
                            codePath,
                            jsonPath
                    ).collect(Collectors.toList());
                    Map<String, String> placeholder = MapUtil.builder(new HashMap<String, String>()).put(sateName, "PLACEHOLDER").build();
                    String msgTemplate = JSONUtil.toJsonStr(placeholder);
                    String results = ExecUtil.execPythonWithMsgTemplate(command, sseId, msgTemplate);
                    resList.add(results);
                }catch (ProcessStopException ps) {
                    isStop.set(true);
                }catch (Exception e) {
                    log.error("动态修正系统计算评估-计算异常，异常信息:{}", e.getMessage());
                    e.printStackTrace();
                } finally {
                    File file = needDelete.get();
                    if (file != null && file.exists()) {
                        //FileUtil.del(file);
                    }
                }
            });
        }).collect(Collectors.toList());

        CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).thenRun(() -> {
            SseEmitterUtils.sendMessage(sseId,"600");
            SseEmitterUtils.remove(sseId);
        }).join();


        if (isStop.get()) {
            throw new ProcessStopException("动态修正系数计算评估已终止");
        }


        List<String> pathList = resList.stream()
                .flatMap(o -> {
                    String substring = o.substring(o.indexOf("["));
                    JSONArray jsonArray = JSONUtil.parseArray(substring);
                    List<String> list = jsonArray.toList(String.class);
                    return list.stream();
                })
                .filter(o -> StrUtil.isNotBlank(o) && !"None".equalsIgnoreCase(o))
                .distinct()
                .collect(Collectors.toList());

        Map<String, Object> resMap = new HashMap<>();
        resMap.put("resultData", JSONUtil.toJsonStr(pathList));
        resMap.put("module", ResultSaveModule.MODEL_CORRECT);
        resMap.put("submodule", ResultSaveModule.MODEL_CORRECT_CAL);

        return AjaxResult.success(resMap);
    }

    @GetMapping("/audit")
    @ApiOperation(value = "动态修正系数分析-查询", notes = "根据时间范围筛选目录", httpMethod = "GET")
    public AjaxResult auditDir(CorrectCoefficientVo vo) {
        //查询接口：入参是起始结束日期，然后去output目录modelCorrect下寻找所有符合日期的，返回他们名字的一个数组给前端，数据结构：
        //
        //["397__417km_2003-10-24-00-00-00__2003-10-24-12-00-00","397__417km_2003-10-24-00-00-00__2003-10-24-12-00-00",...]
        //
        //   重点：拿到所有符合条件的目录后，要判断每个目录下是否存在 目录A（397__417km 2003-10-24-00-00-00 2003-10-24-12-00-00）/visualized_data/equivalent_Tc.txt, 固定的文件名，
        //   如果不存在，则删除目录A，也不用返回给前端了。
        String findPath = PathUtil.outputDir() + PathUtil.moduleDirs().getModelCorrect().get("dir");
        //假如前端传：2023-10-01    2023-10-02
        //则要查找 2023-10-01 00:00:00		2023-10-01 12:00:00
        //         2023-10-01 12:00:00		2023-10-02 00:00:00
        //         2023-10-02 00:00:00		2023-10-02 12:00:00
        //         2023-10-02 12:00:00		2023-10-03 00:00:00
        //生成这样的目录列表，然后挨个去查找
        Date startDate = DateUtil.parseDate(vo.getStartTime());
        Date endDate = DateUtil.parseDate(vo.getEndTime());
        Calendar calendar = CalendarUtil.calendar(endDate);
        calendar.add(Calendar.DATE,1);
        endDate = calendar.getTime();

        List<String> allDirTimeNameList = DateUtil
                .rangeToList(startDate, endDate, DateField.DAY_OF_YEAR)
                .stream()
                .map(DateUtil::formatDate)
                .flatMap(o -> Stream.of(o + "-00-00-00", o + "-12-00-00"))
                .distinct()
                .collect(Collectors.toList());
        List<String> finalTimeNameList = allDirTimeNameList.subList(0, allDirTimeNameList.size() - 1);


        List<String> results = IntStream.range(0, finalTimeNameList.size())
                .mapToObj(i -> finalTimeNameList.get(i) + "__" + finalTimeNameList.get((i + 1) % finalTimeNameList.size()))
                .limit(finalTimeNameList.size() - 1) //去除最后一个元素
                .collect(Collectors.toList());

        log.debug("查找的范围是：{}",results);

        List<String> finalList = results.stream().map(matchStr -> {
                    List<File> specNameDirs = CommonUtil.findSpecNameDirs(findPath, matchStr);
                    if (CollUtil.isEmpty(specNameDirs)) {
                        return new ArrayList<String>();
                    }
                    return specNameDirs.stream().filter(o -> {
                        String verifyFile = o.getAbsolutePath() + "/visualized_data/equivalent_Tc.txt";
                        File file = new File(verifyFile);
                        log.debug("正在判断file:{}是否存在, 结果:{}", verifyFile, file.exists());
                        if (!file.exists()) {
                            FileUtil.del(o);
                            return false;
                        }
                        return true;
                    }).map(File::getName).collect(Collectors.toList());
                }).collect(Collectors.toList())
                .stream()
                .collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll);

        if (CollUtil.isEmpty(finalList)){
            return AjaxResult.error("没有找到相关的目录");
        }
        return AjaxResult.success(finalList);
    }

    //
    @GetMapping("/coeSates")
    @ApiOperation(value = "修正系数验证卫星列表获取", notes = "根据时间范围筛选目录", httpMethod = "GET")
    public AjaxResult coeSates(CorrectCoefficientVo vo) throws Exception {

        //根据选中的“397__417km_2003-10-24-00-00-00__2003-10-24-12-00-00” 中的时间去查询数据库中：SWDATA_OBS_DEN_* 的表，只要表中存在这个时间范围的记录，则该卫星就加入到列表中返给前端，数据结构：
        //["GRACEA","CHAMP",...]

        String dirName = vo.getDirName();
        String[] split = dirName.split("km_");
        String[] timeRangeSplit = split[1].split("__");

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        Date startDate = simpleDateFormat.parse(timeRangeSplit[0]);
        Date endDate = simpleDateFormat.parse(timeRangeSplit[1]);
        String startDateStr = DateUtil.formatDateTime(startDate);
        String endDateStr = DateUtil.formatDateTime(endDate);

        //先去数据库中查一下有那些表 符合 SWDATA_OBS_DEN_*
        try{
            List<String> tableNames = dataCollectionMapper.selectAllTableNames("piesat_dgdq"); //大写最好
            if (CollUtil.isEmpty(tableNames)){
                return AjaxResult.error("模式: {} 下没有找到任何数据库表");
            }

            List<String> sortedNames = tableNames
                    .stream()
                    .map(String::toUpperCase)
                    .filter(name -> name.contains("SWDATA_OBS_DEN_"))
                    .collect(Collectors.toList());

            List<String> finalTables = sortedNames.stream().filter(tableName -> {
                return dataCollectionMapper.exitsRecords(tableName, startDateStr, endDateStr) > 0;
            }).collect(Collectors.toList());

            if (CollUtil.isEmpty(finalTables)){
                return AjaxResult.error("模式: {} 下没有找到任何符合搜索条件的数据库表");
            }
            List<String> sateNames = finalTables.stream().map(o -> o.replace("SWDATA_OBS_DEN_", "")).collect(Collectors.toList());
            return AjaxResult.success(sateNames);
        }catch (Exception e){
            e.printStackTrace();
        }
        return AjaxResult.error("没有找到任何符合搜索条件的数据库表");
    }


    @PostMapping("/verify")
    @ApiOperation(value = "分析结果-确定", notes = "分析结果-确定", httpMethod = "POST")
    public AjaxResult verifyResult(@RequestBody CorrectCoefficientVo vo){

        Map<String,Object> resultMap = new HashMap<>();

        //任务1
        //python：python3 verify_coe_modelling.py /dgdq/**/**/397__417km_2003-10-19-00-00-00__2003-10-19-12-00-00/visualized_data/coe_*.txt CHAMP ，
        // 不打印进度条，结果A 截取###返回给前端，结果A是【修正系数精度验证结果的table】。
        String codePath = PathUtil.codeDir() +
                PathUtil.moduleDirs().getModelCorrect().get("dir") +
                PathUtil.moduleDirs().getModelCorrect().get("verify");

        String outputDir = PathUtil.outputDir() +
                PathUtil.moduleDirs().getModelCorrect().get("dir");
        String dirName = vo.getDirName();
        String time = dirName.split("km_")[1];
        // /dgdq/output/modelCorrect/397__417km_2003-10-16-12-00-00__2003-10-17-00-00-00/visualized_data/coe_2003-10-16-12-00-00__2003-10-17-00-00-00.txt
        String workDir = outputDir + "/" + dirName + "/visualized_data";
        String resultTxtPath = workDir + "/coe_"+time+".txt";
        String sateName = vo.getSateName();

        //python verify_coe_modelling.py /dgdq/output/modelCorrect/397__417km_2003-10-19-00-00-00__2003-10-19-12-00-00/visualized_data/coe_2003-10-19-00-00-00__2003-10-19-12-00-00.txt CHAMP
        String command = "python "+codePath+" "+resultTxtPath+" "+sateName;
        String results = ExecUtil.execCmdWithResult(command);
        if (results == null || !results.contains("###")){
            return AjaxResult.error(results);
        }

        String tableData = results.split("###")[1];
        List<Map> tableDataMap = JSONUtil.parseArray(tableData.replaceAll("\n", "")).toList(String.class)
                .stream().map(o -> JSONUtil.toBean(o , Map.class)).collect(Collectors.toList());
        resultMap.put("tableData", tableDataMap);

        //任务2
        //workDir = /dgdq/output/modelCorrect/397__417km_2003-10-16-12-00-00__2003-10-17-00-00-00/visualized_data
        //1.密度测量数据预处理结果

        String observationCheckPath = workDir + "/observation_check.txt";
        List<String> observationCheckDataList = CommonUtil.readLineDataByStart(new File(observationCheckPath), 2, null);
        if (CollUtil.isEmpty(observationCheckDataList)){
            resultMap.put("observationCheckMap", Constants.BLANK);
        }else {
            List<String> timeList = new ArrayList<>();
            List<String> normalList = new ArrayList<>();
            List<String> abnormalList = new ArrayList<>();

            if (CollUtil.isNotEmpty(observationCheckDataList)){

                observationCheckDataList.forEach( o -> {
                    String[] split = o.split("\t\t");
                    timeList.add(split[0]);
                    normalList.add(split[1]);
                    abnormalList.add(split[2]);
                });
            }
            Map<String, Object> observationCheckMap = MapUtil.builder(new HashMap<String, Object>())
                    .put("timeList", timeList)
                    .put("normalList", normalList)
                    .put("abnormalList", abnormalList)
                    .build();

            resultMap.put("observationCheckMap", observationCheckMap);
        }

        //2.密度数据覆盖性分析结果
        String picPath = workDir + "/subpoint.jpg";
        resultMap.put("picPath", picPath);

        //3.密度数据残差计算结果
        //在 workDir 中用“modeled_density_validation_”前缀去遍历
        String validationMatchStr = "modeled_density_validation_";
        List<File> validationNameFiles = CommonUtil.findSpecNameFiles(workDir, validationMatchStr);
        if (CollUtil.isEmpty(validationNameFiles)){
            resultMap.put("validation", Constants.BLANK);
        }else {

            //每个文件都要生成表1和表2，表1是3个一维数组，表2是2个一维数组
            List<File> sortedFiles = validationNameFiles.stream().sorted(Comparator.comparing(File::getName)).collect(Collectors.toList());
            Map<String,Object> validationMap = new LinkedHashMap<String,Object>();
            sortedFiles.forEach(file -> {

                String fileName = file.getName().split("\\.")[0];
                List<String> dataStrList = CommonUtil.readLineDataByStart(file, 2, null);
                Map<String, List<Object>> collectMap = dataStrList.stream().collect(TreeMap::new, (map, dataStr) -> {
                    String[] split = dataStr.split("\t\t");
                    map.compute("time", calculateFunction(split[3].trim()));
                    map.compute("simulate", calculateFunction(split[5].trim()));
                    map.compute("observe", calculateFunction(split[6].trim()));
                    map.compute("dif", calculateFunction(CommonUtil.scientificSubtract(split[5].trim(),split[6].trim())));
                }, (map1, map2) -> {
                });

                //table1包含 time、simulate、observe
                Map<String, List<Object>> densityMap = collectMap.entrySet().stream()
                        .filter(entry -> !"dif".equals(entry.getKey()))
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                //table2包含 time、dif
                Map<String, List<Object>> difMap = collectMap.entrySet().stream()
                        .filter(entry -> "dif".equals(entry.getKey()) || "time".equals(entry.getKey())).
                        collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

                Map<String, Object> tables = MapUtil.builder(new HashMap<String, Object>())
                        .put("densityMap", densityMap)
                        .put("difMap", difMap)
                        .build();

                validationMap.put(fileName, tables);

            });
            resultMap.put("validation", validationMap);
        }

        //4.修正系数收敛性分析结果
        //在 workDir 中用 “calibration_coefficient_” 前缀去遍历
        String coefficientMatchStr = "calibration_coefficient_";
        List<File> coefficientNameFiles = CommonUtil.findSpecNameFiles(workDir, coefficientMatchStr);
        if (CollUtil.isEmpty(coefficientNameFiles)){
            resultMap.put("coefficient", Constants.BLANK);
        }else {

            List<File> sortedFiles = coefficientNameFiles.stream().sorted(Comparator.comparing(File::getName)).collect(Collectors.toList());
            Map<String,Object> coefficientMap = new LinkedHashMap<String,Object>();
            sortedFiles.stream().forEach(file -> {

                String mapKey = file.getName().replace(coefficientMatchStr, "").split("\\.")[0]; //calibration_coefficient_C00.txt

                List<String> dataStrList = CommonUtil.readLineDataByStart(file, 2, null);
                Map<String, List<Object>> collectMap =  dataStrList.stream().collect(TreeMap::new, (map, dataStr) -> {
                    String[] split = dataStr.split("\t\t");
                    map.compute("x", calculateFunction(split[0].trim()));
                    map.compute("y", calculateFunction(split[1].trim()));
                }, (map1, map2) -> {
                });
                coefficientMap.put(mapKey, collectMap);
            });
            resultMap.put("coefficient", coefficientMap);
        }

        //5.温度修正量分析结果

        String filePath = workDir + "/equivalent_Tc.txt";
        List<String> dataStrList = CommonUtil.readLineDataByStart(new File(filePath), 2, null);
        if (CollUtil.isEmpty(dataStrList)){
            resultMap.put("correct", Constants.BLANK);
        }else {
            Map<String, List<Object>> collectMap =  dataStrList.stream().collect(TreeMap::new, (map, dataStr) -> {
                String[] split = dataStr.split("\t\t");
                map.compute("correct_after", calculateFunction(split[0].trim())); //这个int类型的key只是我们用来排序的，顺从TreeMap的默认升序
                map.compute("correct_before", calculateFunction(split[1].trim()));
                map.compute("x", calculateFunction(split[5].trim()));
            }, (map1, map2) -> {
            });
            resultMap.put("correct", collectMap);
        }

        //6.修正系数计算结果：/coe_*.txt，

        dataStrList = CommonUtil.readLineDataByStart(new File(resultTxtPath), 2, null);
        if (CollUtil.isEmpty(dataStrList)){
            resultMap.put("result", Constants.BLANK);
        }else {

            Map<String, List<Object>> collectMap =  dataStrList.stream().collect(TreeMap::new, (map, dataStr) -> {
                String[] split = dataStr.split("\t\t");
                map.compute("x", calculateFunction(split[0].trim()));
                map.compute("y", calculateFunction(split[1].trim()));
            }, (map1, map2) -> {
            });
            resultMap.put("result", collectMap);
        }

        //7.修正系数精度验证结果：
        String finalDataPath = workDir + "/verified_data.txt";
        List<String> finalDataStrList = CommonUtil.readLineDataByStart(new File(finalDataPath), 2, null);
        if (CollUtil.isEmpty(finalDataStrList)){
            resultMap.put("verifyResult", Constants.BLANK);
        }else {
            Map<String, List<Object>> collectMap =  finalDataStrList.stream().collect(TreeMap::new, (map, dataStr) -> {
                String[] split = dataStr.split("\t\t");
                map.compute("x", calculateFunction(split[0].trim()));
                map.compute("dynamic", calculateFunction(split[1].trim()));
                map.compute("jacchia", calculateFunction(split[2].trim()));
                map.compute("observe", calculateFunction(split[3].trim()));
            }, (map1, map2) -> {
            });
            resultMap.put("verifyResult", collectMap);
        }

        return AjaxResult.success(resultMap);

    }

    private static BiFunction<String,List<Object>,List<Object>> calculateFunction(Object element){
        return (key,list) ->{
            if (list == null) list = new ArrayList<>();
            list.add(element);
            return list;
        };
    }





    @ApiOperation(value = "建立连接", notes = "建立连接")
    @GetMapping(path = "subscribe", produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
    public SseEmitter push(String id, String flag) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        return SseEmitterUtils.connect(id+loginUser.getUsername(), flag);
    }


    public static void main(String[] args) {
        Date startDate = DateUtil.parseDate("2023-10-01");
        Date endDate = DateUtil.parseDate("2023-10-02");
        Calendar calendar = CalendarUtil.calendar(endDate);
        calendar.add(Calendar.DATE,1);
        endDate = calendar.getTime();

        List<String> allDirTimeNameList = DateUtil
                .rangeToList(startDate, endDate, DateField.DAY_OF_YEAR)
                .stream()
                .map(DateUtil::formatDate)
                .flatMap(o -> Stream.of(o + "-00-00-00", o + "-12-00-00"))
                .distinct()
                .collect(Collectors.toList());
        List<String> finalTimeNameList = allDirTimeNameList.subList(0, allDirTimeNameList.size() - 1);

        finalTimeNameList.forEach(System.out::println);
    }


}
